#ifndef MATRIX_3_H_
#define MATRIX_3_H_

#include "Quaternion.h"
/* Designed purely for use with Intertia tensors, which themselves are designed
 * to record how hard it is to rotate an object around a specific axis 
*/
/* Also used in billboard applications to retrieve the cameras current 
 * rotation 
*/
/* Collumb major formating 
 *[0] [3] [6]
 *[1] [4] [7]
 *[2] [5] [8]
 **/
class Matrix3
{
public:
    /* Public member data to allow faster set ups */
    float m_data[9];
public:
    /* Default Ctr */
    Matrix3();
    /* Ctr overloads */
    Matrix3(const Vec3f& one, const Vec3f& two, const Vec3f& three);
    Matrix3(float c0,float c1,float c2,float c3,float c4,float c5,float c6,float c7,float c8);
    /* Set functions */
    void SetComponents(const Vec3f& one, const Vec3f& two, const Vec3f& three);
    void SetDiagonal(float a, float b, float c);
    void SetInertiaTensorCoeffs(float ix, float iy, float iz,
                                     float ixy = 0, float ixyz= 0, float iyz = 0);
    void SetBlockInertiaTensor(const Vec3f& vec, float mass);
    /* Operator overloads */
    Vec3f operator*(const Vec3f& other) const;
    Matrix3 operator*(const Matrix3& o) const;
    Matrix3& operator*=(const Matrix3& o);
    Matrix3& operator*=(const float scale);
    Matrix3& operator+=(const Matrix3& o);

    /* Transofmr the given vector by this matrix */
    Vec3f Transform(const Vec3f& v) const;
    /* Transform the given vector by the transpose of this matrix. */
    Vec3f TransformTranspose(const Vec3f& v) const;
    /* Allows fast access to data in vector form */
    Vec3f GetRow(int index) const;
    /* returns a copy of this matrix, inverted */
    Matrix3 GetInverse() const;
    /* invert this matrix */
    Matrix3& Invert();

    /* Set this matrix to be the inverse of the given matrix */
    void SetInverse(const Matrix3& m);

    /* multiply this matrix by the given quaternion */
    void SetOrientation(const Quaternion& q);
    /* Sets the matrix to be a skew symmetric matrix, 
     * based on the given Vector.
     * Equivalent of cross product for matrixes, ie, 90 degrees to each other?
       vec A cross vec B = Symetic Matrix M * b                            */
    void SetScewSymmetric(const Vec3f& vec);

    /* Usefull for billboards */
    void SetTranspose(const Matrix3& m);
    Matrix3 Transpose() const;

    /* Good for debugging */
    void Print() const;
};

#endif